/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.datalogging.filter;

import org.apache.commons.beanutils.MethodUtils;
import org.openmrs.api.OpenmrsService;
import org.openmrs.module.datalogging.enums.FilterType;

import java.util.Hashtable;
import java.util.Map;

/**
 *
 */
public class Filter {
	
	private String filterName;
	
	/**
	 * The service that need to be executed to get the filter value
	 */
	private OpenmrsService service;
	
	/**
	 * Mapping of method name in the service and the service they provide
	 */
	private Map<FilterType, String> typeHandler;
	
	/**
	 * @param filterName
	 * @param service
	 */
	public Filter(String filterName, OpenmrsService service) {
		this.filterName = filterName;
		this.service = service;
	}
	
	/**
	 * Return the value of the filterName
	 * 
	 * @return the filterName
	 */
	public String getFilterName() {
		return filterName;
	}
	
	/**
	 * Set the filterName with the filterName value
	 * 
	 * @param filterName the filterName to set
	 */
	public void setFilterName(String filterName) {
		this.filterName = filterName;
	}
	
	/**
	 * Return the value of the service
	 * 
	 * @return the service
	 */
	public OpenmrsService getService() {
		return service;
	}
	
	/**
	 * Set the service with the service value
	 * 
	 * @param service the service to set
	 */
	public void setService(OpenmrsService service) {
		this.service = service;
	}
	
	/**
	 * Return the value of the typeHandler
	 * 
	 * @return the typeHandler
	 */
	public Map<FilterType, String> getTypeHandler() {
		return typeHandler;
	}
	
	/**
	 * Set the typeHandler with the typeHandler value
	 * 
	 * @param typeHandler the typeHandler to set
	 */
	public void setTypeHandler(Map<FilterType, String> typeHandler) {
		this.typeHandler = typeHandler;
	}
	
	/**
	 * @param filterType
	 * @param methodName
	 */
	public void addTypeHandler(FilterType filterType, String methodName) {
		if (getTypeHandler() == null)
			setTypeHandler(new Hashtable<FilterType, String>());
		getTypeHandler().put(filterType, methodName);
	}
	
	/**
	 * @param filterType
	 */
	public String getTypeHandler(FilterType filterType) {
		return getTypeHandler().get(filterType);
	}
	
	/**
	 * @param filterType
	 * @return
	 */
	public Boolean isFilterTypeSupported(FilterType filterType) {
		return getTypeHandler().containsKey(filterType);
	}
	
	/**
	 * @param nameOrId
	 * @return
	 * @throws Exception
	 */
	public Object getFilterValue(String nameOrId) throws Exception {
		try {
			Integer id = Integer.parseInt(nameOrId);
			return MethodUtils.invokeMethod(service, getTypeHandler(FilterType.OBJECT_ID), id);
		} catch (Exception e) {
			return MethodUtils.invokeMethod(service, getTypeHandler(FilterType.FULL_NAME), nameOrId);
		}
	}
	
	/**
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public Object getFilterValues(String name) throws Exception {
		return MethodUtils.invokeMethod(service, getTypeHandler(FilterType.PARTIAL_NAME), name);
	}
}
